package com.example.service;

import org.ansj.domain.Result;
import org.ansj.domain.Term;
import org.ansj.splitWord.analysis.NlpAnalysis;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 自然语言处理服务，用于分词、实体识别和关系抽取
 */
@Service
public class NlpService {

    /**
     * 分词处理
     */
    public List<String> segment(String text) {
        List<String> words = new ArrayList<>();
        Result result = NlpAnalysis.parse(text);
        for (Term term : result.getTerms()) {
            words.add(term.getName());
        }
        return words;
    }

    /**
     * 从问题中提取实体（优先匹配知识图谱中存在的实体）
     */
    public List<String> extractEntities(String question, List<String> knownEntities) {
        List<String> entities = new ArrayList<>();

        // 优先匹配已知实体
        for (String entity : knownEntities) {
            if (question.contains(entity) && entity.length() > 1) { // 过滤太短的实体
                entities.add(entity);
            }
        }

        // 如果没有匹配到已知实体，尝试通过词性标注提取可能的实体
        if (entities.isEmpty()) {
            Result result = NlpAnalysis.parse(question);
            for (Term term : result.getTerms()) {
                // 提取名词、人名、地名、机构名等可能的实体
                if (term.getNatureStr().startsWith("n") ||
                        term.getNatureStr().startsWith("nr") ||
                        term.getNatureStr().startsWith("ns") ||
                        term.getNatureStr().startsWith("nt")) {
                    entities.add(term.getName());
                }
            }
        }

        return entities;
    }

    /**
     * 从问题中抽取关系类型
     */
    public String extractRelation(String question) {
        // 关系映射：问题中的关键词 -> 知识图谱中的关系类型
        String[][] relationMappings = {
                {"建立", "建立"},
                {"创建", "建立"},
                {"建造", "建立"},
                {"定都", "定都"},
                {"位于", "定都"},
                {"属于", "属于"},
                {"归类于", "属于"},
                {"统治", "统治"},
                {"管理", "统治"},
                {"消灭", "消灭"},
                {"灭亡", "消灭"},
                {"击败", "消灭"},
                {"出生", "出生于"},
                {"生于", "出生于"},
                {"死亡", "死于"},
                {"卒于", "死于"}
        };

        // 标准化问题：去除标点，转为小写
        String processedQuestion = question.replaceAll("[^a-zA-Z0-9\u4e00-\u9fa5]", "")
                .toLowerCase();

        // 匹配关系关键词
        for (String[] mapping : relationMappings) {
            String questionKeyword = mapping[0];
            String kgRelationType = mapping[1];
            if (processedQuestion.contains(questionKeyword)) {
                return kgRelationType;
            }
        }

        // 如果没有明确匹配的关系，根据问题模式推断
        return inferRelationFromPattern(processedQuestion);
    }

    /**
     * 从问题模式中推断关系类型
     */
    private String inferRelationFromPattern(String question) {
        // 问题模式与关系的映射
        Pattern whatPattern = Pattern.compile("什么是.*");
        Pattern whoPattern = Pattern.compile("谁是.*");
        Pattern wherePattern = Pattern.compile(".*在哪里.*");
        Pattern typePattern = Pattern.compile(".*属于什么.*");
        Pattern createPattern = Pattern.compile(".*谁建立的.*");

        Matcher matcher;

        if ((matcher = whatPattern.matcher(question)).matches() ||
                (matcher = whoPattern.matcher(question)).matches()) {
            return "描述"; // 对应实体描述
        } else if ((matcher = wherePattern.matcher(question)).matches()) {
            return "定都"; // 地点相关默认按定都处理
        } else if ((matcher = typePattern.matcher(question)).matches()) {
            return "属于"; // 类型相关
        } else if ((matcher = createPattern.matcher(question)).matches()) {
            return "建立"; // 创建者相关
        }

        return null;
    }

    /**
     * 判断问题是询问头实体还是尾实体
     * 例如："谁建立了秦朝？" 是询问头实体
     * "秦始皇建立了什么？" 是询问尾实体
     */
    public boolean isAskingForHeadEntity(String question, List<String> entities) {
        if (entities.isEmpty()) {
            return false;
        }

        String entity = entities.get(0);
        int entityPos = question.indexOf(entity);

        // 常见的询问头实体的模式
        Pattern headPatterns = Pattern.compile("谁|哪个.*(建立|创建|统治|消灭).*");

        // 如果实体在句尾，且有询问头实体的模式，大概率是询问头实体
        if (entityPos > question.length() - entity.length() - 3 ||
                headPatterns.matcher(question).find()) {
            return true;
        }

        return false;
    }


}
